package com.sky.service.user.impl;

import com.alibaba.fastjson.JSON;
import com.sky.context.BaseContext;
import com.sky.dto.OrdersSubmitDTO;
import com.sky.exception.BaseException;
import com.sky.mapper.MerchantMapper;
import com.sky.mapper.user.AddressBookMapper;
import com.sky.mapper.user.OrderDetailMapper;
import com.sky.mapper.user.OrderMapper;
import com.sky.mapper.user.ShoppingCartMapper;
import com.sky.pojo.*;
import com.sky.service.user.UserOrderService;
import com.sky.utils.MapUtils;
import com.sky.vo.OrderSubmitVO;
import com.sky.websocket.WebSocketServer;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.time.Duration;
import java.time.LocalDateTime;
import java.util.*;

/**
 * @Description TODO
 * @Author bo.li
 * @Date 2024/10/16 16:46
 * @Version 1.0
 */
@Service
@Slf4j
@RequiredArgsConstructor
public class UserOrderServiceImpl implements UserOrderService {

    private final ShoppingCartMapper cartMapper;
    private final MerchantMapper merchantMapper;
    private final AddressBookMapper addressBookMapper;
    private final OrderMapper orderMapper;
    private final OrderDetailMapper orderDetailMapper;
    private final RedisTemplate redisTemplate;
    private final WebSocketServer webSocketServer;

    @Override
    public LocalDateTime getEstimatedDeliveryTime(Long shopId, String address) {
        //规则： 预计送达时间 = 当前时间 + 菜品制作时间 + 配送时间 + 预留时间(10分)
        //获取菜品制作时间,购物车里面的数据
        Integer makeTime = cartMapper.getMakeTime(BaseContext.getCurrentId());
        log.info("菜品耗时：{}分",makeTime);
        //查询商家地址
        Merchant merchant = merchantMapper.getById(shopId);
        Map<String, String> map = MapUtils.gaodeTwoPointCostDistanceAndTimeByAddress(merchant.getShopAddress(), address);
        String duration = map.get("duration");
        log.info("配送时间：{}秒",duration);
        //计算总共耗时，秒
        Long time = makeTime*60 + Long.parseLong(duration) + 600;
        LocalDateTime localDateTime = LocalDateTime.now().plusSeconds(time);
        return localDateTime;
    }

    @Override
    @Transactional
    public OrderSubmitVO submit(OrdersSubmitDTO submitDTO) {
        //setnx  分布式锁
        String key = "ORDER-CREATE:" + BaseContext.getCurrentId();
        Boolean flag = redisTemplate.opsForValue().setIfAbsent(key, "aaa", Duration.ofSeconds(10));
        if(!flag){
            log.info("没有获取到锁，不执行");
            throw new BaseException("请务重复提交");
        }

        log.info("获取到锁，可以执行");
        //搞清楚： 本质就是存两张表 订单表和明细表  先存订单表，然后获取订单id再存明细表
        //所有的逻辑就一个，封装表里面需要的数据
        Orders orders = new Orders();
        BeanUtils.copyProperties(submitDTO,orders);
        orders.setNumber(UUID.randomUUID().toString());
        orders.setUserId(BaseContext.getCurrentId());
        orders.setOrderTime(LocalDateTime.now());
        orders.setPayStatus(Orders.UN_PAID);
        orders.setAmount(submitDTO.getAmount());   //一定不能前端的
        orders.setStatus(Orders.PENDING_PAYMENT);

        AddressBook addressBook = addressBookMapper.getById(submitDTO.getAddressBookId());
        if(addressBook == null){
            throw new BaseException("地址错误");
        }
        orders.setUserName(addressBook.getConsignee());
        orders.setConsignee(addressBook.getConsignee());
        orders.setPhone(addressBook.getPhone());
        orders.setAddress(addressBook.getProvinceName() + addressBook.getCityName() + addressBook.getDistrictName() + addressBook.getDetail());
        //出餐时间，当前时间+菜品制作时间
        Integer makeTime = cartMapper.getMakeTime(BaseContext.getCurrentId());
        orders.setMealTime(LocalDateTime.now().minusMinutes(makeTime));
        orderMapper.insert(orders);

        //插入订单详情表
        List<ShoppingCart> shoppingCarts = cartMapper.getByUserId(BaseContext.getCurrentId());
        if(CollectionUtils.isEmpty(shoppingCarts)){
            throw new BaseException("购物车没有数据");
        }
        List<OrderDetail> orderDetailList = new ArrayList<>();
        for (ShoppingCart shoppingCart : shoppingCarts) {
            OrderDetail detail = new OrderDetail();
            BeanUtils.copyProperties(shoppingCart,detail);
            detail.setOrderId(orders.getId());
            orderDetailList.add(detail);
        }
        orderDetailMapper.insertBatch(orderDetailList);

        //清除购物车
        cartMapper.deleteByUserId(BaseContext.getCurrentId());

        OrderSubmitVO vo = OrderSubmitVO.builder().orderAmount(orders.getAmount())
                .orderTime(orders.getOrderTime())
                .id(orders.getId())
                .orderNumber(orders.getNumber()).build();

        return vo;
    }

    @Override
    public void paySuccess(String number) {
        //更新订单状态
        Orders orders = orderMapper.getByNumber(number);
        if(orders == null){
            log.info("订单号不存在：{}",number);
            return;
        }
        orders.setPayStatus(Orders.PAID);
        orders.setStatus(Orders.TO_BE_CONFIRMED);
        orderMapper.updateOrderPaySuccess(orders);
        //发送websocket通知
        Map<String,Object> map = new HashMap<>();
        map.put("type",1);
        map.put("orderId",orders.getId());
        map.put("content","你有新的订单了，请及时处理");

        webSocketServer.sendOrderComeReminder(JSON.toJSONString(map));
    }
}